import java.math.*;
import java.util.concurrent.locks.*;
import org.lsmp.djep.groupJep.groups.Zn;

public class Utilities{
    
    public static final ReentrantLock lock = new ReentrantLock();

    //Field variables - change here for a global change.
    public static int n; 
    public static int n_prime;
    public static int t;
    public static int t_prime;

    public static int T;

    public static BigInteger F_big;
    public static int F;

    public static int tripleAmount;
    public static int l;
    public static int genTripAmount;

    public static Zn zn;

    public static long time;
    public static int mode;

    public static final int Error = -1;
    public static final int shareSecret = 0;
    public static final int doubleShareRandom = 1;
    public static final int receiveCheckDoubleShare = 2;
    public static final int checkDoubleShare = 3;
    public static final int DOUBLESHARE_WAITFORCHECK = 50;
    public static final int reconsPubl = 4;
    public static final int returnReconsPubl = 5;
    public static final int compPhaseReconsPriv = 6;
    public static final int compPhaseReconsPrivFinal = 7;

    public static final int GENTRIP = 10;
    public static final int COMPPHASE = 11;

    public static final int INPUTGATE = 12;
    public static final int OUTPUTGATE = 13;
    public static final int ADDGATE = 14;
    public static final int CONSTGATE = 15;
    public static final int MULTGATE = 16;

    public static final int FAULTDETECTION = 17;
    public static final int FAULTDETECTION_PART2 = 18;
    public static final int FAULTLOCALIZATION = 19;
    public static final int ACCUSATION = 20;
    public static final int ACCUSATIONRESPONSE = 21;

    public static final boolean DEBUG = true; //determines how much info is printed

    public static void update(int n_, int mode_, int mGates){
        n = n_;
        n_prime = n;
        t = n/3;
        t_prime = n_prime/3;
        T = n-(2*t);

        F_big = BigInteger.valueOf(n*2).nextProbablePrime();
        F = F_big.intValue();

        zn = new Zn(F_big);

        mode = mode_;
        if(mode == 1)
            tripleAmount = n+2;

        if(mode == 2 || mode == 3)
            tripleAmount = n+mGates;

        double tmp = (double)Utilities.n / 3.0;
        if((double)Utilities.t == tmp)
            Utilities.t = Utilities.t-1;

        tmp = (double)n_prime / 3.0;
        if((double)Utilities.t_prime == tmp)
            Utilities.t_prime = Utilities.t_prime-1;

        T = n_prime-(2*t_prime);        

        Utilities.l = tripleAmount/Utilities.t;
        tmp = (double)Utilities.tripleAmount / (double)Utilities.t;
        if(Utilities.l < tmp)
            Utilities.l = Utilities.l+1;
        
        Utilities.genTripAmount = l/T;
        tmp = (double)Utilities.l / (double)Utilities.T;
        if(Utilities.genTripAmount < tmp)
            Utilities.genTripAmount = Utilities.genTripAmount+1;
    }

    public static void playersEliminated(){
        //we know 2 players are removed, so we can update
        //accordingly. The rest of the variables are still correct.
        Utilities.n_prime = Utilities.n_prime-2;
        Utilities.t_prime = Utilities.t_prime-1;
    }

}